package com.newbee.smack;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.Roster.SubscriptionMode;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Type;
import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.muc.InvitationListener;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.json.JSONObject;

import android.util.Log;

import com.newbee.activity.tab.ConfigActivity;
import com.newbee.activity.tab.NewFriendsActivity;
import com.newbee.app.AppConfig;
import com.newbee.fragement.multchat.MultChatFragement;
import com.newbee.listbean.FriendsInfoBean;
import com.newbee.service.MainService;
import com.newbee.service.MainServiceKey;
import com.newbee.service.MainServiceTask;
import com.newbee.service.TaskType;

public class SmackClient
{

	public static Connection connection;
	private static ConnectionConfiguration config = new ConnectionConfiguration(
			AppConfig.SMACK_HOST, AppConfig.SMACK_PORT);

	private static SmackClient smackClient = new SmackClient();

	public static int SERVER_NAME_LENGTH = 0;
	public static String SERVER_NAME;

	public static Map<String, MultiUserChat> mMultChatMap = new HashMap<String, MultiUserChat>();

	public static InvitationListener invitationListener = new InvitationListener()
	{

		@Override
		public void invitationReceived(Connection conn, String roomsName,
				String arg2, String arg3, String arg4, Message arg5)
		{
			Log.d("wch", "invite-------------------------------->msg");
			Map<String, Object> pars = new HashMap<String, Object>();

			pars.put(MainServiceKey.MULT_CHAT_ROOM_NAME, roomsName);

			MainServiceTask mst = new MainServiceTask(
					TaskType.INVITE_MULT_CHAT, pars,
					ConfigActivity.class.getName());
			MainService.addTaskQueue(mst);
		}
	};

	private SmackClient()
	{

	}

	public static synchronized SmackClient getInstance()
	{

		return smackClient;
	}

	public void initConfig() throws XMPPException
	{
		/** 是否启用压缩 */
		config.setCompressionEnabled(true);
		/** 是否启用安全验证 */
		config.setSASLAuthenticationEnabled(false);
		/** 是否启用调试 */
		config.setDebuggerEnabled(false);
		config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
		/** 创建connection链接 */
		connection = new XMPPConnection(config);
		/** 建立连接 */
		connection.connect();
		connection.addConnectionListener(new ConnectionListener()
		{
			
			@Override
			public void reconnectionSuccessful()
			{
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void reconnectionFailed(Exception arg0)
			{
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void reconnectingIn(int arg0)
			{
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void connectionClosedOnError(Exception arg0)
			{
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void connectionClosed()
			{
				try
				{
					connection.connect();
				}
				catch (XMPPException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		});
		SERVER_NAME = connection.getServiceName();
		SERVER_NAME_LENGTH = SERVER_NAME.length();
	}

	public boolean fixPassword(String password)
	{
		try
		{
			connection.getAccountManager().changePassword(password);
			return true;
		}
		catch (XMPPException e)
		{
			e.printStackTrace();
			return false;
		}
	}

	public void registUser(String email, String password) throws XMPPException
	{
		connection.getAccountManager().createAccount(email, password);

	}

	public void createAccount(String account, String password)
			throws XMPPException
	{
		connection.getAccountManager().createAccount(account, password);
	}

	public void userLog(String account, String password) throws Exception
	{
		connection.login(account, password);
		MultiUserChat.addInvitationListener(connection, invitationListener);
	}

	public void logout()
	{
		connection.disconnect();
	}

	public List<FriendsInfoBean> getAllFriedns()
	{
		List<FriendsInfoBean> list = new ArrayList<FriendsInfoBean>();
		Roster roster = connection.getRoster();
		for (RosterEntry e : roster.getEntries())
		{

			list.add(new FriendsInfoBean(null, null, e.getUser(), (roster
					.getPresence(e.getUser()).toString()
					.startsWith("available") ? true : false)));

		}
		return list;
	}

	public List<String> getAllFriendsID()
	{
		List<String> list = new ArrayList<String>();
		Roster roster = connection.getRoster();
		for (RosterEntry e : roster.getEntries())
		{
			list.add(e.getUser());
		}
		return list;
	}

	public void acceptAskFriend(String from, String to) throws XMPPException
	{

		Presence presence = new Presence(Type.subscribed);
		presence.setTo(from);
		presence.setFrom(to);
		connection.sendPacket(presence);
		presence = new Presence(Type.subscribed);
		presence.setTo(to);
		presence.setFrom(from);
		connection.sendPacket(presence);

		Log.d("wch", "from--------------------->" + from);
		Roster roster = connection.getRoster();
		String account = from.replace("\\40", "@");

		account.substring(0, account.length() - SERVER_NAME_LENGTH - 1);
		roster.createEntry(from, account, null);
		MainServiceTask mst = new MainServiceTask(TaskType.GET_FRIEND, null,
				NewFriendsActivity.class.getName());
		MainService.addTaskQueue(mst);
	}

	public void refushAskFriend(String from, String to)
	{
		Presence presence = new Presence(Type.unavailable);
		presence.setTo(from);
		presence.setFrom(to);
		connection.sendPacket(presence);
	}

	public void addFriend(String account) throws XMPPException
	{

		String str = account.replace("@", "\\40");
		Roster roster = connection.getRoster();
		Log.d("WCH", "Add friend---------> " + str + "@" + SERVER_NAME);
		roster.createEntry(str + "@" + SERVER_NAME, str, null);
		String to = str + "@" + SERVER_NAME;
		String from = connection.getUser();
		Presence presence = new Presence(Type.subscribed);
		presence.setTo(to);
		presence.setFrom(from);
		connection.sendPacket(presence);
		presence.setTo(from);
		presence.setFrom(to);
		connection.sendPacket(presence);

	}

	public void createMultChat(String MutlChatName, List<String> userList)
			throws XMPPException
	{

		MultiUserChat inviteMuc = new MultiUserChat(connection, connection
				.getUser().split("@")[0]
				+ "$"
				+ MutlChatName
				+ "@conference."
				+ SERVER_NAME);
		// 创建聊天室
		inviteMuc.create(connection.getUser());

		Form submitForm = inviteMuc.getConfigurationForm().createAnswerForm();
		// 聊天是否永远存在
		submitForm.setAnswer("muc#roomconfig_persistentroom", false);
		// 允许占有者邀请其他人
		submitForm.setAnswer("muc#roomconfig_allowinvites", true);
		// 能够发现占有者真实 JID 的角色
		submitForm.setAnswer("muc#roomconfig_enablelogging", false);
		// 仅允许注册的昵称登录
		submitForm.setAnswer("x-muc#roomconfig_reservednick", false);
		// 允许使用者修改昵称
		submitForm.setAnswer("x-muc#roomconfig_registration", false);
		inviteMuc.sendConfigurationForm(submitForm);
		final String roomName = MutlChatName;

		mMultChatMap.put(roomName, inviteMuc);// 纯md5

		inviteMuc.addMessageListener(new PacketListener()
		{
			String from;

			@Override
			public void processPacket(Packet packet)
			{

				Message msg = (Message) packet;
				from = msg.getFrom();
				Map<String, Object> paras = new HashMap<String, Object>();
				paras.put(MainServiceKey.MULT_CHAT_FROM, from);
				paras.put(MainServiceKey.MULT_CHAT_ROOM_NAME, roomName);// 无
				paras.put(MainServiceKey.MULT_CHAT_BODY, msg.getBody());
				MainServiceTask mst = new MainServiceTask(
						TaskType.MULT_CHAT_MSG, paras, MultChatFragement.class
								.getName());
				MainService.addTaskQueue(mst);

			}
		});

		for (String user : userList)
		{
			inviteMuc.invite(user, "");
		}

	}

	public void acceptInviteMultChat(String roomName) throws XMPPException
	{

		MultiUserChat mc = new MultiUserChat(connection, roomName
				+ "@conference." + connection.getServiceName());

		String[] array = roomName.split("\\$");// 这个地方使用的是纯的32位md5
		final String pureRoomName = array[array.length - 1];

		mc.addMessageListener(new PacketListener()
		{

			@Override
			public void processPacket(Packet packet)
			{

				String from;

				if (packet instanceof Message)
				{
					Message msg = (Message) packet;
					from = msg.getFrom();
					Map<String, Object> paras = new HashMap<String, Object>();
					paras.put(MainServiceKey.MULT_CHAT_FROM, from);
					paras.put(MainServiceKey.MULT_CHAT_ROOM_NAME, pureRoomName);
					paras.put(MainServiceKey.MULT_CHAT_BODY, msg.getBody());
					MainServiceTask mst = new MainServiceTask(
							TaskType.MULT_CHAT_MSG, paras,
							MultChatFragement.class.getName());
					MainService.addTaskQueue(mst);
				}
			}
		});
		mMultChatMap.put(pureRoomName, mc);

		mc.join(connection.getUser());
	}

	public void initAddFriendListener()
	{

		PacketFilter filter = new AndFilter(
				new PacketTypeFilter(Presence.class));

		final Roster roster = connection.getRoster();
		roster.setSubscriptionMode(SubscriptionMode.manual);
		connection.addPacketListener(new PacketListener()
		{

			@Override
			public void processPacket(Packet packet)
			{

				if (packet instanceof Presence)
				{
					Presence presence = (Presence) packet;
					String from = presence.getFrom();// 发送方
					String to = presence.getTo();// 接收方
					MainServiceTask mst;
					// Presence.Type有7中状态
					if (presence.getType().equals(Presence.Type.subscribe))
					{
						// 好友申请

						Map<String, Object> paras = new HashMap<String, Object>();
						paras.put(MainServiceKey.ASK_FOR_FRIEND_POCKET_TO, to);
						paras.put(MainServiceKey.ASK_FOR_FRIEND_POCKET_FROM,
								from);

						mst = new MainServiceTask(TaskType.ASK_FOR_FRIEND,
								paras, ConfigActivity.class.getName());
						MainService.addTaskQueue(mst);
						Log.d("WCH",
								"message----------------------------------->send");
					}
					else if (presence.getType()
							.equals(Presence.Type.subscribed))
					{// 同意添加好友

					}
					else if (presence.getType().equals(
							Presence.Type.unsubscribe))
					{// 拒绝添加好友 和 删除好友

					}
					else if (presence.getType().equals(
							Presence.Type.unsubscribed))
					{

					}
					else if (presence.getType().equals(
							Presence.Type.unavailable))
					{
						// 好友下线
						mst = new MainServiceTask(TaskType.GET_FRIEND, null,
								NewFriendsActivity.class.getName());
						MainService.addTaskQueue(mst);

					}
					else
					{
						// 好友上线
						mst = new MainServiceTask(TaskType.GET_FRIEND, null,
								NewFriendsActivity.class.getName());
						MainService.addTaskQueue(mst);
					}
				}

			}
		}, filter);
	}

	public String getAccount()
	{
		return connection.getUser();
	}

	public void sendMultMsg(String roomname, String voiceName, String durtime,
			String msg_type) throws XMPPException
	{

		MultiUserChat muc = mMultChatMap.get(roomname);

		if (muc != null)
		{
			Map<String, String> paras = new HashMap<String, String>();
			paras.put(MultChatFragement.JSON_KEY_DUR, durtime);
			paras.put(MultChatFragement.JSON_KEY_MSG, voiceName);
			paras.put(MultChatFragement.JSON_KEY_TYPE, msg_type);
			JSONObject json = new JSONObject(paras);
			muc.sendMessage(json.toString());

		}

	}

	public void MultChatInitReg(final String roomName) throws XMPPException
	{

		MultiUserChat multiUserChat = new MultiUserChat(connection, roomName
				+ "@conference." + connection.getServiceName());
		multiUserChat.join(connection.getUser());
		multiUserChat.addMessageListener(new PacketListener()
		{

			@Override
			public void processPacket(Packet packet)
			{
				String from;

				if (packet instanceof Message)
				{
					Message msg = (Message) packet;
					from = msg.getFrom();
					Map<String, Object> paras = new HashMap<String, Object>();
					paras.put(MainServiceKey.MULT_CHAT_FROM, from);
					paras.put(MainServiceKey.MULT_CHAT_ROOM_NAME, roomName
							+ "@conference." + connection.getServiceName());
					paras.put(MainServiceKey.MULT_CHAT_BODY, msg.getBody());
					MainServiceTask mst = new MainServiceTask(
							TaskType.MULT_CHAT_MSG, paras,
							MultChatFragement.class.getName());
					MainService.addTaskQueue(mst);
				}

			}
		});

		mMultChatMap.put(
				roomName + "@conference." + connection.getServiceName(),
				multiUserChat);

	}

	public static void removeMultChat(String roomName)
	{

		if (mMultChatMap.containsKey(roomName))// 纯md5
		{
			mMultChatMap.remove(roomName);
		}

	}

}
